<template>
  <div class="data-type">
    <a-select class="data-select" v-model:value="dataType">
      <a-select-option value="static">静态</a-select-option>
      <a-select-option value="http">HTTP请求</a-select-option>
    </a-select>
  </div>
  <div class="string-array-editor" v-if="dataType === 'static'">
    <div class="string-array-items">
      <div class="item" v-for="(item, index) in strArr" :key="index">
        <input type="text" v-model="strArr[index]" />
        <button @click="deleteItem(index)">删除</button>
      </div>
    </div>
    <div class="toolbar">
      <button @click="addItem">+</button>
    </div>
  </div>
  <div class="http-string-array-editor" v-if="dataType === 'http'">
    <div class="row">
      <div>参数类型</div>
      <a-select class="data-select" v-model:value="paramType">
        <a-select-option value="params">PARAMS</a-select-option>
        <a-select-option value="body">BODY</a-select-option>
      </a-select>
    </div>
    <div class="row" v-if="paramType === 'params'">
      <div>请求类型</div>
      <a-select class="data-select" v-model:value="httpMethod">
        <a-select-option value="GET">GET</a-select-option>
        <a-select-option value="POST">POST</a-select-option>
        <a-select-option value="PUT">PUT</a-select-option>
        <a-select-option value="DELETE">DELETE</a-select-option>
      </a-select>
    </div>
    <div class="row" v-if="paramType === 'body'">
      <div>请求体参数类型</div>
      <a-select class="data-select" v-model:value="bodyType">
        <a-select-option value="application/json">application/json</a-select-option>
        <a-select-option value="plain/text">plain/text</a-select-option>
      </a-select>
    </div>
    <div class="row" v-if="paramType === 'body'">
      <div>请求参数</div>
      <a-textarea class="data-select" v-model:value="bodyData" placeholder="请输入请求体数据" :rows="4" />
    </div>
    <div class="row">
      <div>请求地址</div>
      <a-input class="data-select" v-model:value="url" />
    </div>
  </div>
</template>

<script lang="ts">
import { defineComponent, PropType, Ref, ref, onMounted, watchEffect, watch, reactive } from 'vue'
import axios, { AxiosRequestConfig } from 'axios'

const echartsAxios = axios.create({})

const defaultStringArray: string[] = []
export default defineComponent({
  props: {
    value: {
      type: Array as PropType<string[]>,
      default: defaultStringArray,
    },
  },
  setup(props) {
    const dataType: Ref<'static' | 'http'> = ref('static')
    const paramType: Ref<'params' | 'body'> = ref('params')
    const bodyType: Ref<'application/json' | 'plain/text'> = ref('application/json')
    const httpMethod: Ref<'GET' | 'POST' | 'PUT' | 'DELETE'> = ref('GET')
    const url: Ref<string> = ref('')
    const bodyData: Ref<string> = ref('{}')
    const strArr = ref<string[]>(props.value)

    const fetchRemoteStringArray = (config: AxiosRequestConfig) => {
      echartsAxios(config).then((resp) => {
        strArr.value.splice(0)
        strArr.value.push(...resp.data.data as string[])
      }).catch(err => {
        console.error(err)
      })
    }

    const addItem = () => {
      strArr.value.push('')
    }
    const deleteItem = (itemIndex: number) => {
      strArr.value.splice(itemIndex, 1)
    }

    const config = reactive<AxiosRequestConfig>({
      url: url.value,
      method: httpMethod.value,
    })
    watch([url, httpMethod, bodyType, paramType, bodyData], (
      [newUrl, newMethod, newBodyType, newParamType, newBodyData],
      [oldUrl, oldMethod, oldBodyType, oldParamType, oldBodyData]
    ) => {
      config.url = newUrl
      config.method = newMethod

      let requestBody: any = {}
      const reqyestHeader: { 'Content-Type'?: string } = {}
      if (paramType.value === 'body') {
        requestBody = JSON.parse(newBodyData)
        reqyestHeader['Content-Type'] = newBodyType
      }
      config.data = requestBody
      config.headers = reqyestHeader
    }, {
      deep: true,
      flush: 'post'
    })
    watch(config, (newVal, oldVal) => {
      fetchRemoteStringArray(newVal)
    }, {
      deep: true,
      flush: 'post'
    })
    onMounted(() => {
      fetchRemoteStringArray(config)
    })

    return {
      dataType,
      paramType,
      bodyType,
      httpMethod,
      bodyData,
      url,
      strArr,
      addItem,
      deleteItem,
    }
  },
})
</script>

<style scoped>
.data-type {
  margin-bottom: 10px;
}

.data-select {
  width: 150px;
}
</style>
